package com.hedl.practice.diyJava.annotation.definition;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Range;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Main {
    public static void main(String[] args) throws IllegalAccessException {
        System.out.println(Person.class.isAnnotationPresent(DefinitionAnnotation.class));

        System.out.println("----------------");

        //获取Person定义的@DefinitionAnnotation注解:
        DefinitionAnnotation annotation = Person.class.getAnnotation(DefinitionAnnotation.class);
        int type = annotation.type();
        System.out.println("type的默认值："+type);
        String level = annotation.level();
        System.out.println("level的默认值："+level);

        System.out.println("----------------");

        //使用反射API读取Annotation有两种方法;
        // 方法一是先判断Annotation是否存在，如果存在，就直接读取：
        /*Class cls = Person.class;
        if (cls.isAnnotationPresent(DefinitionAnnotation.class)){
            DefinitionAnnotation definitionAnnotation = cls.getAnnotation(DefinitionAnnotation.class);
        }
        */
        if (Person.class.isAnnotationPresent(DefinitionAnnotation.class)){
            DefinitionAnnotation definitionAnnotation = Person.class.getAnnotation(DefinitionAnnotation.class);
            System.out.println("存在！");
        }

        //第二种方法是直接读取Annotation，如果Annotation不存在，将返回null：
        if (annotation != null){
            System.out.println("不等于空！");
        }

        System.out.println("--------------------");

        /**
         * 读取方法、字段和构造方法的Annotation和Class类似。
         * 但要读取方法参数的Annotation就比较麻烦一点，因为方法参数本身可以看成一个数组，
         * 而每个参数又可以定义多个注解，所以，一次获取方法参数的所有注解就必须用一个二维数组来表示
         */

        Class cls = Person.class;
        try {
            ////获取Method实例:
            Method m = cls.getMethod("hello", String.class, String.class);
            //获取所有参数的Annotation:
            Annotation[][] annos = m.getParameterAnnotations();
            //第一个参数（索引为0）的所有Annotation:
            Annotation[] annosOfName = annos[0];
            for (Annotation anno : annosOfName) {
                if (anno instanceof Range){
                    Range r = (Range) anno;
                }
                if (anno instanceof NotNull){
                    NotNull n = (NotNull) anno;
                }
            }
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }

        System.out.println("===================");

    }
    public void check(Person person) throws IllegalAccessException {
        //遍历所有Field:
        for (Field field : person.getClass().getFields()){
            //获取Field定义的@Range:
            Ranges range = field.getAnnotation(Ranges.class);
            //如果@Range存在:
            if (range != null){
                //获取Field的值:
                Object value = field.get(person);
                //如果值是String:
                if (value instanceof String){
                    String s = (String) value;
                    //判断值是否满足@Range的min/max:
                    if (s.length() < range.min() || s.length() > range.max()){
                        throw new IllegalArgumentException("Invalid field:"+field.getName());
                    }
                }
            }
        }
    }
}
